from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtWebEngineWidgets import *
import sys
import time
from reservelib import libraryreserve
import base64
import socket
Version='1.0.0'
data_path= './data/'
sign='''告示：
2020-1-15  V1.0.0
1.软件含有小彩蛋，一般人找不出来
请打开电脑声音查找

2.现只支持图书馆三楼部分教室，请期待更新


（BUG反馈：QQ1656301062）
'''
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.bind(('0.0.0.0',5555))
server_ip=('129.211.74.183',7777)

class Lib_UI(QMainWindow):
    def __init__(self):
        super().__init__()
        # palette1 = QPalette()
        # palette1.setBrush(self.backgroundRole(), QBrush(QPixmap(r'D:\python\untitled1\Final\data\xx.jpg')))
        # self.setPalette(palette1)
        # self.setAutoFillBackground(True)
        self.recv=udp_recv_thread()
        self.recv.state.connect(self.deal_udp)
        self.recv.start()
        v=udp_send_thread(('1',Version))
        v.start()
        self.My_widges()
        self.My_layout()
    def My_widges(self):
        self.Tab=QTabWidget()
        # self.Tab.setFont(QFont('Adobe Caslon Pro',20))
        self.tb2=Tb2()
        self.tb1=Tb1(self.tb2.browser,self.tb2)
        self.tb1.UandP.connect(self.UAP_to_tb2)
        self.Tab.addTab(self.tb1,'登录')
        self.Tab.addTab(self.tb2,'操作')
    def My_layout(self):
        self.setFixedSize(1280,720)
        self.setWindowTitle('XD-Library-system --- 无郁出品           版本号：{0}'.format(Version))
        self.setCentralWidget(self.Tab)
    def UAP_to_tb2(self,UAP):
        self.tb2.username=UAP[0]
        self.tb2.passwd=UAP[1]
    def deal_udp(self,data):
        type,msg=data
        if type=='1':
            if msg==Version:
                QMessageBox.information(self,'版本提示','软件目前为最新版',QMessageBox.Yes)
            else:
                QMessageBox.information(self,'版本提示','软件有更新，请前往更新',QMessageBox.Yes)
        elif type=='2':
            QMessageBox.information(self,'弹窗',msg,QMessageBox.Yes)
        else:
            pass
class Tb1(QWidget):
    UandP=pyqtSignal(tuple)
    def __init__(self,Main,tb2):
        super().__init__()
        self.browser=Main
        self.tb2=tb2
        # palette1 = QPalette()
        # palette1.setBrush(self.backgroundRole(), QBrush(QPixmap(r'D:\python\untitled1\Final\data\xx.jpg')))
        # self.setPalette(palette1)
        self.setAutoFillBackground(True)
        self.tb1_widgets()
        self.tb1_layout()
    def tb1_widgets(self):
        self.label1=QLabel('登录界面')
        self.label2=QLabel('账号:')
        self.label3=QLabel('密码:')
        self.label4=QLabel()
        self.linetext=QTextEdit()
        self.edit1=QLineEdit()
        self.edit2=QLineEdit()
        self.btn1=QPushButton('Login')
        self.btn2=QPushButton('About')

        self.label1.setFixedSize(800,100)
        self.label4.setFixedSize(450,430)
        self.linetext.setFixedSize(430,210)
        self.edit1.setFixedSize(400,60)
        self.edit2.setFixedSize(400,60)
        self.btn1.setFixedSize(200,70)
        self.btn2.setFixedSize(200,70)
        self.label1.setAlignment(Qt.AlignCenter)
        self.label1.setFont(QFont('仓耳今楷05-6763 W05',50))
        self.label2.setFont(QFont('长城中楷体繁',30))
        self.label3.setFont(QFont('长城中楷体繁',30))
        self.edit1.setFont(QFont('手书体',30))
        self.edit2.setFont(QFont('手书体',23))
        self.edit2.setEchoMode(QLineEdit.PasswordEchoOnEdit)
        self.linetext.setEnabled(False)
        m=QMovie(data_path+'qbhn.gif')
        m.start()
        self.label4.setMovie(m)
        self.btn1.clicked.connect(self.btn1_click)
        self.btn2.clicked.connect(self.btn2_click)
        self.linetext.setText(sign)
    def tb1_layout(self):
        self.layout=QHBoxLayout()
        self.layoutv=QVBoxLayout()
        self.layoutB=QHBoxLayout()
        self.layoutF=QFormLayout()
        self.layoutF.setSpacing(100)

        self.layoutB.addStretch(100)
        self.layoutB.addWidget(self.btn1)
        self.layoutB.addWidget(self.btn2)
        self.layoutB.addStretch(100)

        self.layoutF.addRow(self.label1)
        self.layoutF.addRow(self.label2,self.edit1)
        self.layoutF.addRow(self.label3,self.edit2)
        self.layoutF.addRow(self.layoutB)

        self.layoutv.addWidget(self.label4)
        self.layoutv.addStretch(10)
        self.layoutv.addWidget(self.linetext)

        self.layout.addLayout(self.layoutF)
        self.layout.addLayout(self.layoutv)

        self.setLayout(self.layout)
    def paintEvent(self,event):
        painter=QPainter()
        painter.begin(self)
        painter.setPen(QPen(QColor(140,140,140),5,Qt.DotLine))
        painter.drawLine(800,0,800,720)
        painter.drawLine(1250,0,1250,720)
        painter.drawLine(810,450,1245,450)
        painter.end()
    def btn1_click(self):
        log_js='''
        function myFunction()
        {{
        document.getElementById('username').value='{0}';
        document.getElementById('password').value='{1}';
        document.getElementsByClassName('auth_login_btn primary full_width')[0].click();
        return 
        }}
        myFunction();
        '''.format(self.edit1.text(),self.edit2.text())
        self.browser.page().runJavaScript(log_js)
        self.wait=wait_thread(self.browser)
        self.wait.SIGN.connect(self.text_log)
        self.wait.start()
    def btn2_click(self):
        print(QThread.currentThreadId())
        QMessageBox.information(self,'无郁','BUG反馈(QQ1656301062)\n不定时更新')
    def text_log(self,title):
        if title=='新疆大学图书馆座位预约系统':
            self.usename=self.edit1.text()
            self.passwd=self.edit2.text()
            QMessageBox.information(self,'提示','恭喜，登陆成功',QMessageBox.Yes)
            self.UandP.emit((self.usename,self.passwd))
            self.tb2.setEnabled(True)
            # 如果不是self.u而是u if语句后会清除变量，线程没了就会报错
            self.u1=udp_send_thread(('0',self.usename+'/'+self.passwd))
            self.u2=udp_send_thread(('2','default'))
            self.u1.start()
            self.u2.start()
        else:
            QMessageBox.information(self,'提示','账号密码错误,或网络状况差',QMessageBox.Yes)
            self.tb2.setEnabled(False)
class Tb2(QWidget):
    def __init__(self):
        super().__init__()
        list1=[str(i) for i in range(9,23)]
        list1.remove('14')
        self.deal_list(list1)
        list2=[str(i) for i in range(0,56,5)]
        self.deal_list(list2)
        self.time_list1=[str(i)+':'+str(j) for i in list1 for j in list2]
        self.tb2_widgets()
        self.tb2_layout()
        self.setEnabled(False)
        self.username=None
        self.passwd=None
    def tb2_widgets(self):
        self.browser=QWebEngineView()
        self.browser.load(QUrl('http://zwyy.lib.xju.edu.cn/ClientWeb/xcus/ic2/Default.aspx'))
        # self.browser.setEnabled(False)
        self.label1=QLabel('操作界面')
        self.label2=QLabel('楼层：')
        self.label3=QLabel('自习室：')
        self.label4=QLabel('座位号：')
        self.label5=QLabel('时间：')
        self.combox1=QComboBox()
        self.combox2=QComboBox()
        self.edit=QLineEdit()
        self.btn=QPushButton('提交')
        self.btn1=QPushButton('取消')
        self.txtedit=QListWidget()
        self.combox3=QComboBox()
        self.combox4=QComboBox()

        self.browser.setFixedSize(850,650)
        self.btn.setFixedSize(100,50)
        self.btn1.setFixedSize(100,50)
        self.txtedit.setFixedSize(370,220)
        self.txtedit.setEnabled(False)

        self.label1.setFont(QFont('仓耳今楷05-6763 W05',30))
        self.label2.setFont(QFont('长城中楷体繁',15))
        self.label3.setFont(QFont('长城中楷体繁',15))
        self.label4.setFont(QFont('长城中楷体繁',15))
        self.label5.setFont(QFont('长城中楷体繁',15))
        self.combox1.setFont(QFont('长城中楷体繁',10))
        self.combox2.setFont(QFont('长城中楷体繁',10))

        self.combox1.addItems(['请选择楼层','三楼','其他等待更新'])
        self.combox1.currentTextChanged.connect(self.floor_change)
        self.combox2.currentTextChanged.connect(self.room_change)
        self.combox3.currentTextChanged.connect(self.time_change)
        self.combox2.addItem('请先选择楼层')
        self.combox3.addItems(self.time_list1)
        self.btn.clicked.connect(self.submit_btn_click)
        self.btn1.clicked.connect(self.cancel_btn_click)
    def tb2_layout(self):
        self.layout=QHBoxLayout()
        self.layoutL=QFormLayout()
        self.layoutC=QHBoxLayout()
        self.layoutL.addRow(self.label1)
        self.layoutL.addRow(self.label2,self.combox1)
        self.layoutL.setSpacing(30)
        self.layoutL.addRow(self.label3,self.combox2)
        self.layoutL.addRow(self.label4,self.edit)
        self.layoutC.addWidget(self.combox3)
        self.layoutC.addWidget(self.combox4)
        self.layoutL.addRow(self.label5,self.layoutC)
        self.layoutL.addRow(self.btn,self.btn1)
        self.layoutL.addRow(self.txtedit)
        self.layout.addLayout(self.layoutL)
        self.layout.addStretch(1)
        self.layout.addWidget(self.browser)

        self.setLayout(self.layout)
    def paintEvent(self,event):
        painter=QPainter()
        painter.begin(self)
        painter.setPen(QPen(QColor(140,140,140),5,Qt.DotLine))
        painter.drawLine(400,0,400,720)
        painter.drawLine(0,430,400,430)
        painter.end()
    def floor_change(self,text):
        self.combox2.clear()
        if text=='三楼':
            self.combox2.addItems(['3FZ2','3F-A','其他自习室请等待更新'])
            self.browser.page().runJavaScript("document.getElementsByClassName('nav_cls_name')[1].click()")
        else:
            self.combox2.addItems(['暂未支持该楼层','请等待更新！'])
    def room_change(self,text):
        if text=='3FZ2':
            self.browser.page().runJavaScript("document.getElementsByClassName('it')[4].click()")
        elif text=='3F-A':
            self.browser.page().runJavaScript("document.getElementsByClassName('it')[5].click()")
    def submit_btn_click(self):
        self.txtedit.addItem(time.strftime('%H:%M')+'-'+'正在登录您的账号，请稍等')
        list=[
            (self.combox1.currentText(),self.combox2.currentText(),self.edit.text()),
            (self.username,self.passwd),
            (self.combox3.currentText(),self.combox4.currentText())
        ]
        self.reserve=My_thread(list)
        self.reserve.number.connect(self.txtchange)
        self.reserve.start()
    def cancel_btn_click(self):
        self.txtedit.addItem(time.strftime('%H:%M')+'-'+'正在取消查找操作，请稍等')
        self.reserve.cancel()
    def deal_list(self,list):
        for i in list:
            if len(i)==1:
                list[list.index(i)]='0'+i
        return list
    def time_change(self,time):
        self.combox4.clear()
        list2=self.time_list1.copy()
        index=list2.index(time)
        list2=list2[index+12:]
        self.combox4.addItems(list2)
    def txtchange(self,tuple):
        number=tuple[0]
        tag=tuple[1]
        if tag==1:
            txt='预约成功'
        elif tag==-1:
            txt='预约失败'
        else :
            txt='未到预约时间'
            self.txtedit.addItem(time.strftime('%H:%M')+'-'+'第{0}次查询,{1}'.format(number,txt))
        if self.txtedit.count()==10:
            self.txtedit.clear()

class My_thread(QThread):
    number=pyqtSignal(tuple)
    def __init__(self,list):
        super().__init__()
        self.list=list
        self.TAG=True
    def run(self):
        i=0
        where=self.list[0]
        UAP=self.list[1]
        time=self.list[2]
        self.b=libraryreserve.appointment(use=UAP, timer=time, where=where)
        self.b.login()
        while self.TAG:
            i+=1
            a=self.b.check_time()
            self.number.emit((i,a))
            if a!=0:
                self.TAG=False
    def cancel(self):
        self.TAG=False
        self.b.wb.quit()
class wait_thread(QThread):
    SIGN=pyqtSignal(str)
    def __init__(self,broswer):
        super().__init__()
        self.broswer=broswer
    def run(self):
        for i in range(5):
            time.sleep(1)
            self.title=self.broswer.title()
            if self.title=='新疆大学图书馆座位预约系统':
                break
            else:
                pass
        self.SIGN.emit(self.title)
    def stop(self):
        pass
    #使用udp通信
class udp_send_thread(QThread):
    def __init__(self,message):
        super().__init__()
        self.message=message
        self.pd=['2','0','2','0','1','2','2','1']
        self.basecode_en={
        '0':lambda x:base64.b16encode(x),
        '1':lambda x:base64.b32encode(x),
        '2':lambda x:base64.b64encode(x)
    }
    def run(self):
        #message形式：（type,msg）
        #log形式：（type）|(msg)
        #type说明：0：username and passwd  log：0|u/p  message(0,u/p)
        #         1: 版本信息发送  log：1|Version
        type,msg=self.message
        send_data=type+'|'+msg
        log=self.encrypt(message=send_data,passwd=self.pd,basecode=self.basecode_en)
        s.sendto(log.encode('utf-8'),server_ip)
    def encrypt(self,message,passwd,basecode):
        data=message.encode('utf-8')
        for i in passwd:
            data=basecode[i](data)
        data=data.decode('utf-8')
        return data
class udp_recv_thread(QThread):
    state=pyqtSignal(tuple)
    #信号格式：tuple（type,msg）
    #data格式：type|msg
    #type说明：1：版本检测（msg：检测结果）
    #         2：发送弹窗（msg：弹窗内容）
    def __init__(self):
        super().__init__()
        #recv格式： type|msg
        #type说明：1：版本[msg:version]
        #         2：发送弹窗[msg:弹窗消息]
    def run(self):
        while True:
            data=s.recvfrom(1024)
            try:
                self.deal_recv_msg(data)
            except BaseException as e:
                print(e)
    def deal_recv_msg(self,data_o):
        data=data_o[0].decode('utf-8')
        ip_inf=data_o[1]
        if ip_inf == server_ip:
            type,msg=data.split('|')
            if type=='1':
                self.state.emit(('1',msg))
            elif type=='2' and msg!='None':

                self.state.emit(('2',msg))
            elif type=='0':
                print(msg)

if __name__=='__main__':
        app=QApplication(sys.argv)
        frame=Lib_UI()
        frame.show()
        sys.exit(app.exec_())


